package com.cheyunkeji.er.http;


import android.text.TextUtils;
import android.view.Gravity;

import com.cheyun.netsalev3.R;
import com.cheyun.netsalev3.MyApplication;
import com.cheyunkeji.er.view.SToast;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.google.gson.internal.$Gson$Types;
import com.google.gson.reflect.TypeToken;
import com.zhy.http.okhttp.callback.Callback;

import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import okhttp3.Call;
import okhttp3.Response;
import okhttp3.ResponseBody;

/** Created by Michael on 2017/4/10 17:04. */
public abstract class RespCallback<T> extends Callback<Resp<T>> {

  private static final String TAG = RespCallback.class.getSimpleName();
  // gson 解析
  private Gson gson;

  public RespCallback() {
    GsonBuilder builder = new GsonBuilder();
    // other setting builder

    gson = builder.create();
  }

  @Override
  public Resp parseNetworkResponse(Response response, int id) throws Exception {

    Resp resp = null;
    ResponseBody responseBody = response.body();
    String string = responseBody.string();

    try {

      JSONObject object = new JSONObject(string);

      if ((int) object.get("code") == -1) {
        onCodeNegative_1();
        return null;
      }

      //          强制退出登录
      if ((int) object.get("code") == -2) {
        onCodeNegative_2(object);
        return null;
      }
      Type t = getType();

      resp = gson.fromJson(trim(string), getType());

//      resp = gson.fromJson(object.get("data").toString(), getType());
    } catch (Exception e) {
      // 错误信息的结构
      resp = gson.fromJson(string, new TypeToken<Resp<ErrorMsg>>() {}.getType());
    } finally {
      responseBody.close();
    }
    return resp;
  }

  @Override
  public void onResponse(Resp<T> response, int id) {

    if (null == response) return;

    try {
      int rtn = response.code;

      switch (rtn) {
          // 响应成功
        case Resp.RESPONSE_SUCCESS:
          onSuccess(response.data);
          break;

        case Resp.RESPONSE_FAIL:
          onRequestFailed(response.msg);
        default:
          break;
      }

      onMsgCount(response.rows);

    } catch (Exception e) {
      onError(e);
    }
  }

  //    请求成功时row字段数据
  protected void onMsgCount(int rows) {}

  //      数据请求失败接口回调
  protected abstract void onRequestFailed(String msg);

  protected abstract void onSuccess(T data);

  //    code 为-1时接口回调
  protected void onCodeNegative_1() {}

  //    code 为-2时接口回调
  protected void onCodeNegative_2(JSONObject obj) {}

  @Override
  public void onError(Call call, Exception e, int id) {

    e.printStackTrace();
    // 取消了请求
    if (call.isCanceled()) {
      return;
    }

    // 服务端和客户端json结构定义不一致 -> 到 parseNetworkResponse定位一下错误
    if (e instanceof JsonSyntaxException) {
      SToast.show(e.getMessage());
      return;
    }
    if (e instanceof RuntimeException) {
      // (response.code() >= 400 && response.code() <= 599) 特殊处理了
      //            SToast.show(e.getMessage());
      SToast.show(R.string.tip_server_error, Gravity.CENTER); // 临时用来处理服务器端报的错
      return;
    }
    onError(e);
  }

  private Type getType() {
    // 当前对象泛型超类->RespCallback
    Type superclass = getClass().getGenericSuperclass();
    if (superclass instanceof Class) {
      // RespCallback可以不传泛型类型
      throw new RuntimeException("Missing type parameter.");
    }

    // 带参数的Type
    ParameterizedType parameter = (ParameterizedType) superclass;
    // 取得泛型类型对应的类型，即得到 T 对应的类型
    Type _type = $Gson$Types.canonicalize(parameter.getActualTypeArguments()[0]);
    return $Gson$Types.newParameterizedTypeWithOwner(null, Resp.class, _type);
  }

  public void onError(Exception e) {
    e.printStackTrace();
    // json 解析语法出错
    if (e instanceof JsonSyntaxException) {
      SToast.show(R.string.tip_system_error, Gravity.CENTER);
      return;
    }

    // 网络异常
    if (e instanceof UnknownHostException || e instanceof SocketException) {
      SToast.show(R.string.tip_network_error, Gravity.CENTER);
      return;
    }
  }

  /** 处理json */
  private static String getJsonString(String source) {
    String result = source;

    if (!TextUtils.isEmpty(result)) {
      if (result.startsWith("var adConfigs =")) {
        result = result.substring("var adConfigs = [ ".length(), result.length() - 2);
      }
      Pattern pattern = Pattern.compile("^\\s*callback\\s*\\((.*)\\s*\\)\\s*$");
      Matcher m = pattern.matcher(source);
      if (m.find() && m.groupCount() > 0) {
        result = m.group(1);
      }

      // 兼容处理 远程下载接口返回JSON多加的 （） 问题
      pattern = Pattern.compile("^\\s*\\((.*)\\s*\\)\\s*$");
      m = pattern.matcher(source);
      if (m.find() && m.groupCount() > 0) {
        result = m.group(1);
      }
    }

    return result;
  }

  // 处理字符串
  private static String trim(String source) {
    return getJsonString(source);
  }
}
